package gui;
import geom.FigureGraphique;
import geom.Point_2D;
import geom.Polygone;

import java.awt.*;
import java.awt.event.MouseEvent;
import java.io.Serializable;
import java.util.Formatter;
import java.util.Vector;

import algo.AlgoElastique;
/**
 * Cette classe est le coeur de l'application elle gere le stockage des figures en memoire
 * et les "ordres" de deplacement et de dessin des figures.
 * @author Romain POGU
 * @author Anthony MAUGENDRE
 * @version 1.0
 *
 */
public class FenetAffiche extends Frame implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = -2402279256668938434L;
	public ZoneDessin zd;
    public boolean isReloading;
	// figures actuellement dessinees
	//Vector<FigureGraphique> figs;
	// Store moving figs in a vector
	//Vector<FigureGraphique> movingFigs;
	// AlgoElastique
	AlgoElastique elastique;
	int xEnfonce, yEnfonce;
	int xRelache, yRelache;
	int thNumber=0;
	Polygone villes;
	// Chemin d'enregistrement du fichier courant.
	String filePath;
	BarreOutils barreOutils;
	// Ajout Elastique
	boolean isRunning;
	boolean deleted;
	/**
	 * Constructeur
	 * @param vec Vector dans lequel les figures seront stockees
	 */
	public FenetAffiche(Vector<FigureGraphique> vec) {
		isRunning=false;
		setSize(800, 600);
		setResizable(false);
		setTitle("Voyageur Elastique");
		setForeground(Color.blue);
		setBackground(Color.gray);
		villes=new Polygone();
		add(zd = new ZoneDessin(this), "Center");
		addWindowListener(new ControleurFenet(this));
		addComponentListener(new GestionFrame(zd));
		barreOutils = new BarreOutils(this);
		add(barreOutils, "West");
		setMenuBar(new BarreMenu(this));
		setVisible(true);
	}
	
	/**
	 * Cette methode permet de remetre l'application dans sont etat de depart
	 */
	public void reset() {
		isRunning = false;
		villes=new Polygone();
		barreOutils.labelLongueurElastique.setText("N/A");
		barreOutils.labelNbVilles.setText("0");
		if(elastique!=null && elastique.isAlive()){
			elastique.interrupt();
		}
		filePath = null;
	}
	public void boutonSourisRelache(int x, int y, int button) {
		xEnfonce = x;
		yEnfonce = y;
		int buttonEnfonce = button;
		//CAS DU POLYGONE
		if (buttonEnfonce == MouseEvent.BUTTON1) {
			Point_2D point = new Point_2D(xEnfonce, yEnfonce);
			villes.addPoint(point);
			barreOutils.labelNbVilles.setText(""+villes.getNbPoints());
			villes.dessineToi(zd.getGraphics());
		}
	}
	/**
	 * Methode qui permet de changer le chemin du fichier de sauvegarde courant
	 * 
	 * @param filePath nouveau chemin du fichier se sauvegarde courant
	 * 
	 */
	public void setFilePath(String filePath) {
		this.filePath = filePath;
	}
	/**
	 * Methode qui permet de savoir s'il exite un fichier de sauvegarde courant
	 * 
	 * @return YES si il n'y a pas de fichier de sauvegarde courant
	 * 
	 */
	public boolean filePathIsNull() {
		return filePath == null;
	}
	public boolean lancerElastique(){
		//TODO appeler algo sur polygon actuel
		if(isRunning || villes.getNbPoints()<3){
			if (villes.getNbPoints()<3) {
                javax.swing.JOptionPane.showMessageDialog(null,"Vous devez entrer au moins 3 villes avant de lancer l'algorithme!");
            }
            return false;
		}
		isRunning=true;
		runAlgoElastique();
		return true;
	}
	
	private void initAlgoElastique(){
		double m=barreOutils.getM();
		double alpha=barreOutils.getAlpha();
		double beta=barreOutils.getBeta();
		double k=barreOutils.getK();
		double r=barreOutils.getR();
		double iterations=barreOutils.getIterations();
		elastique=new AlgoElastique(villes, (int)r, m, k, alpha, beta, (int)iterations,this);
	}
	
	private void runAlgoElastique(){
		//On initialise l'algo

		this.initAlgoElastique();
		//on stop si besoin
		if(elastique!=null && elastique.isAlive()){
			elastique.interrupt();
		}
		//on lance l'algo
		barreOutils.labelLongueurElastique.setText("Calcul en cours...");
		elastique.start();
		//on raffiche le polygon par dessus
		villes.dessineToi(zd.getGraphics());
	}

    public void dessineElastique(Graphics gx) {
			villes.dessineToi(gx);
            if (!isReloading && elastique!=null) {
               runAlgoElastique();
            }
    }
	
	public void stopAlgoElastique(){
		//on stop si besoin
		if(elastique!=null && elastique.isAlive()){
			deleted=true;
			elastique.interrupt();
		}
	}
	
	public void algoStarted(int thNumber){
		this.thNumber=thNumber;
	}
	
	public void algoEnded(int thNumber){
		if(thNumber>=this.thNumber){
			System.out.println("LAST ALGO ENDED");
			barreOutils.toggle.setLabel("Lancer");
			isRunning=false;
			double longueur=elastique.getLongueurElastique();
			Formatter formatter=new Formatter();
			if(longueur>0){
				barreOutils.labelLongueurElastique.setText(""+formatter.format("%10.2f",longueur));
			}else{
				if(deleted){
					zd.repaint();
				}
				barreOutils.labelLongueurElastique.setText("Non calcul�");
			}
		}
		if(deleted){
			deleted=false;
		}
	}
}
